package br.ufmg.ubicomp.droidguide.eventservice;

import java.util.Calendar;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;

import br.ufmg.ubicomp.droidguide.common.DroidGuideConfigurationManager;
import br.ufmg.ubicomp.droidguide.common.DroidGuideConstants;
import br.ufmg.ubicomp.droidguide.communication.EventServiceCommunication;
import br.ufmg.ubicomp.droidguide.eventservice.event.DroidGuideEvent;
import br.ufmg.ubicomp.droidguide.eventservice.event.ServiceEvent;
import br.ufmg.ubicomp.droidguide.eventservice.event.UserEvent;
import br.ufmg.ubicomp.droidguide.eventservice.management.EventManager;
import br.ufmg.ubicomp.droidguide.eventservice.notification.DGNotificationType;
import br.ufmg.ubicomp.droidguide.eventservice.notification.NotificationBucket;
import br.ufmg.ubicomp.droidguide.utils.DateUtil;

public class UserEventHandlingService {

	private static UserEventHandlingService theService;
	
	public static UserEventHandlingService getInstance()
	{
		if (theService == null)
		{
			theService = new UserEventHandlingService();
		}
		return theService;
	}
	
	private UserEventHandlingService() {
	}
	
	public int sendEventsToServer() throws Exception {
			//AndroidUtils.showAlert(context, "Updating events . . .");

			String dgKey = DroidGuideConfigurationManager.getInstance().getData(
					DroidGuideConstants.DROID_GUIDE_USER_KEY);
			
			Collection<DroidGuideEvent> events = 
				sendUserEventsToServer(dgKey);
			
			return events.size();
//		} catch (Exception e) {
//			e.printStackTrace();
//			//AndroidUtils.notifyError(e, context, "SendEventsToServer", "UserEventProcessingService");
//		}
//		return 0;
	}

	public Collection<ServiceEvent> readEventsFromServer() throws Exception
	{
		String dgKey = DroidGuideConfigurationManager.getInstance().getData(
				DroidGuideConstants.DROID_GUIDE_USER_KEY);
		
		Collection<ServiceEvent> events = readServerEventsFromServer(dgKey);				
		
		handleIncommingEvents(events);
		return events;
	}
	
	private void handleIncommingEvents(Collection<ServiceEvent> events) {
		for (ServiceEvent event: events)
		{
			NotificationBucket.getInstance().addNotification(DGNotificationType.INCOMMING, System.currentTimeMillis(), 
					event.getData(), "Server", Level.ALL);
		}
	}
	
	private Collection<DroidGuideEvent> sendUserEventsToServer(String dgKey) throws Exception
	{
		EventManager man = EventManager.getInstance();

		int i = 0;
		Set<DroidGuideEvent> events = new TreeSet<DroidGuideEvent>();;
		for (UserEvent evt: man.getUserEvents())
		{
			// if the event has not been sent to server
			if (!evt.isSentToServer())
			{
				EventServiceCommunication.save(dgKey, 
					evt.getType().getDescription(), 
					evt.getSource().getDescription(), evt.getData());
				evt.setSentToServer(true);
				events.add(evt);
				i++;
			}
		}
		if (!events.isEmpty())
		{
			man.clearEvents();
		}
//		if (DroidGuideConstants.USER_EVENT_STRATEGY_REMOVE_ON_SAVE)
//		{
//			man.clearEvents();
//		}
		NotificationBucket.getInstance().addNotification(
				DGNotificationType.APPLICATION, 
				System.currentTimeMillis(),
				DateUtil.formatDate(Calendar.getInstance(), "hh:mm:ss") + 
				": " + events.size() + " events to server", "UserEvents", Level.FINEST);
		
		return events;
	}

	private Set<ServiceEvent> readServerEventsFromServer(String dgKey) throws Exception {
		Set<ServiceEvent> events = new HashSet<ServiceEvent>();
		Collection<DroidGuideEvent> eventsFromServer = EventServiceCommunication.read(dgKey);
		for (DroidGuideEvent eventFromServer: eventsFromServer)
		{
			//Log.i("UserEventHandlingService", "found incomming events!");
			if (eventFromServer instanceof ServiceEvent)
			{
				events.add((ServiceEvent) eventFromServer);
			}
		}
		return events;
	}
	
	
	public int sendUserEventsToServerOld() throws Exception
	{
		EventManager man = EventManager.getInstance();

		String dgKey = DroidGuideConfigurationManager.getInstance().getData(
				DroidGuideConstants.DROID_GUIDE_USER_KEY);
		int i = 0;
		for (UserEvent evt: man.getUserEvents())
		{
			if (!evt.isSentToServer())
			{
				EventServiceCommunication.save(dgKey, 
					evt.getType().getDescription(), 
					evt.getSource().getDescription(), evt.getData());
				evt.setSentToServer(true);
				i++;
			}
		}
		
		if (DroidGuideConstants.USER_EVENT_STRATEGY_REMOVE_ON_SAVE)
		{
			man.clearEvents();
		}
		return i;
	}
}
